﻿using System;
using System.Collections.Generic;
using UnityEditor;
using UnityEditor.Experimental.GraphView;
using UnityEngine;
using UnityEngine.UIElements;
using EditorPort = UnityEditor.Experimental.GraphView.Port;
namespace NodeEditor
{
    public class NodeItem : Node
    {
        public AbstractNode node;
        public Action<NodeItem> onSelect;
        public Dictionary<string, Port> portDict = new Dictionary<string, Port>();
        private Dictionary<string, Port> displayPortDict = new Dictionary<string, Port>();
        public NodeItem(AbstractNode node)
        {
            this.node = node;
            this.title = node.title;
            this.viewDataKey = node.guid;
            style.left = node.position.x;
            style.top = node.position.y;

            foreach (var port in node.ports)
            {
                displayPortDict.Add(port.displayName, port);
            }

            CreatPort();
            var array = node.DrawGUI();
            foreach (var item in array)
            {
                this.Add(item);
            }
        }

        void CreatPort()
        {
            var type = node.GetType();
            var so = new SerializedObject(node);
            var sp = so.GetIterator();

            while(sp.Next(true))
            {
                if (sp.depth > 0 || sp.displayName == "Script")
                    continue;

                var field = type.GetField(sp.name);
                if (field == null)
                    continue;
                var attr = AttributeUtility.GetAttribute<PortAttribute>(field);
                if (attr == null)
                    continue;

                var dir = attr.isInput ? Direction.Input : Direction.Output;

                var multi = attr.isMulti ? dir == Direction.Input ? EditorPort.Capacity.Single : EditorPort.Capacity.Multi : EditorPort.Capacity.Single;

                if (type == typeof(Root) && dir == Direction.Input)
                    continue;

                CreateObjectPort(sp.displayName,sp.name, dir, multi, attr.type?? field.FieldType);
            }
        }

        void CreateObjectPort(string displayName,string name, Direction direction, EditorPort.Capacity capacity, Type type)
        {
            //创建接口的数据
            Port port;
            if (!displayPortDict.ContainsKey(displayName))
            {
                port = new Port();
                port.guid = GUID.Generate().ToString();
                port.name = name;
                port.displayName = displayName;
                port.direction = direction == Direction.Input ? PortDirection.Input : PortDirection.Output;
                node.ports.Add(port);
            }
            else
            {

                port = displayPortDict[displayName];
            }
           
            //创建接口
            var editorPort = InstantiatePort(Orientation.Horizontal, direction, capacity, type);
            editorPort.portName = displayName;
            editorPort.viewDataKey = port.guid;

            VisualElement container = direction == Direction.Input ? inputContainer : outputContainer;
            container.Add(editorPort);

            portDict.Add(port.guid, port);

        }

        public override void SetPosition(Rect newPos)
        {
            base.SetPosition(newPos);
            node.position = newPos.position;
            node.Save();
        }
        public override void OnSelected()
        {
            base.OnSelected();
            onSelect?.Invoke(this);
        }

    }


  

}
